package com.briup.pts.service.impl;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.briup.pts.config.exception.ServiceException;
import com.briup.pts.config.response.ResultCode;
import com.briup.pts.domain.bean.Animal;
import com.briup.pts.domain.vo.AnimalVO;
import com.briup.pts.mapper.AnimalMapper;
import com.briup.pts.service.AnimalService;
import com.briup.pts.service.HurdlesService;
import com.briup.pts.service.QrcodeService;
import com.briup.pts.service.UploadService;
import com.briup.pts.util.AssertUtil;
import com.briup.pts.util.MockMultipartFile;
import com.briup.pts.util.UuidUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Optional;

/**
 * @author wy
 * @description
 * @data 2024/11/28  9:20
 */
@Service
@RequiredArgsConstructor
public class AnimalServiceImpl implements AnimalService {

    @Value("${qrcode.content}")
    private String content;
    @Value("${qrcode.base-path}")
    private String basePath;
    private final AnimalMapper mapper;
    private final HurdlesService hurdlesService;
    private final UploadService uploadService;
    private final QrcodeService qrcodeService;

    @Override
    public void qrcode(String animalId) throws Exception {
        // 1.校验该动物是否存在
        int count = mapper.countById(animalId);
        AssertUtil.isTrue(count == 1,
                ResultCode.ANIMAL_IS_NOT_EXISTS);

        // 2.生成二维码，得到二维码图片文件
        // 2.1 确定二维码的内容及文件存储的区域
        String content = String.format(this.content, animalId);
        String fileName = String.format(basePath, animalId);
        File file = new File(fileName);
        // 2.2 生成二维码文件
        QrCodeUtil.generate(content, 300, 300, file);

        // 3.将二维码图片文件上传到七牛云中，得到二维码的url地址
        MockMultipartFile multipartFile = new MockMultipartFile(
                fileName, new FileInputStream(file));
        String url = uploadService.uploadToOss(multipartFile);

        // 4.将二维码的地址链接与动物的关系存入数据库表 manager_qrcode中
        new Thread(() -> qrcodeService.addQrcode(animalId, url)).start();

        // 5.将本地的图片删除
        new Thread(() -> {
            boolean ignore = file.delete();
        }).start();
    }

    @Override
    public AnimalVO findByAnimalId(String animalId) {
        AnimalVO animalVO = mapper.findByAnimalId(animalId);
        // 判断动物是否获取到，如果未获取到，抛出异常
        return Optional.ofNullable(animalVO)
                .orElseThrow(() ->
                        new ServiceException(ResultCode.ANIMAL_IS_NOT_EXISTS));
    }

    @Override
    public PageInfo<AnimalVO> pageQueryByCondition(Integer pageNum, Integer pageSize,
                                                 String aHealthy, String aGender) {
        try (Page<AnimalVO> ignored = PageHelper.startPage(pageNum,pageSize)){
            List<AnimalVO> animals= mapper.queryPage(aHealthy,aGender);
            return new PageInfo<>(animals);
        }
    }
    @Transactional
    @Override
    public void saveOrUpdate(Animal animal) {
        // 根据id是否存在，确定是修改还是新增
        String animalId = animal.getAAnimalId();
        if (StringUtils.hasText(animalId)) {
            // id存在，则为修改，又因为修改可能涉及到批次和栏圈的变化，
            // 所以建议先删除在新增回来
            deleteById(animalId);
        } else {
            // 如果前端为传入id，表示新增，而动物id为UUID，所以需要自己设置
            animal.setAAnimalId(UuidUtil.randomUuid());
        }
        // 新增动物数据
        mapper.addAnimal(animal);
        // 修改栏圈的存储量
        hurdlesService.changeSaved(animal.getAHurdlesId(), 1);
    }

    @Override
    public void deleteById(String aAnimalId) {
        // 删除动物数据，需要考虑修改栏圈内以已存储动物的数量
        // 先确定要删除的动物是否存在，以及获取该动物所在的栏圈id
        AnimalVO animalVO = mapper.findByAnimalId(aAnimalId);
        AssertUtil.requiredNotNull(animalVO, ResultCode.ANIMAL_IS_NOT_EXISTS);
        // 动物存在，继续删除数据和修改栏圈数据
        String hurdlesId = animalVO.getAHurdlesId();
        // 根据栏圈id修改栏圈存储量数据
        hurdlesService.changeSaved(hurdlesId,-1);
        // 再而删除动物数据
        mapper.deleteById(aAnimalId);
    }

    @Override
    public void deleteByIdAll(List<String> ids) {
        mapper.deleteByIdAll(ids);
    }
}
